package com.jishuo.pzk.service;

import com.github.pagehelper.PageHelper;
import com.jishuo.base.config.PzkConfig;
import com.jishuo.pzk.bean.base.*;
import com.jishuo.pzk.dao.VoucherMapper;
import com.jishuo.pzk.util.GetBlob;
import com.jishuo.pzk.util.IdWorker;
import com.jishuo.pzk.util.ImageUtils;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class PzkService {
    @Resource
    private VoucherService voucherService;
    @Resource
    private VoucherMapper voucherMapper;
    @Resource
    private PzmessageService pzmessageService;
    @Resource
    private GetBlob getBlob;

    @Value("${pzk.pzkFilePath}")
    private String pzkFilePath;
    @Value("${pzk.scaling}")
    private double scaling;
    @Value("${pzk.compress}")
    private double compress;

    /**
     * 查询可用于绘制的凭证列表。
     * 本方法不接受任何参数，主要进行以下操作：
     * 1. 使用PageHelper分页工具，设置起始页为1，每页显示数量为100；
     * 2. 调用baseDataMapper的listVoucherForDraw方法，查询并返回凭证列表。
     *
     * @return List<VoucherVO> 返回凭证信息的列表，包含满足条件的所有凭证。
     */
    public List<VoucherVO> listVoucherForDraw() {
        // 设置分页信息，起始页为1，每页显示100条
        PageHelper.startPage(1, 100);
        // 调用mapper层方法，查询可用于绘制的凭证列表
        return voucherMapper.listVoucherForDraw();
    }

    /**
     * 绘制凭证
     */
    public void draw() {
        long start = System.currentTimeMillis();
        List<VoucherVO> list = this.listVoucherForDraw();
        // 模板信息
        List<VouTempPageVO> listvp = voucherService.listVouPage();

        // 印章信息
        VouSealVO vv = voucherService.getVouSeal();

        // 印章位置
        List<VouandSealVO> listvs = voucherService.listVouandSeal();

        for (VoucherVO vo : list) {
            // 根据业务类型从配置中获取对应的编码
            // @param vo 业务凭证对象，其中包含了业务类型
            String vocode = PzkConfig.VocodeMap.get(String.valueOf(vo.getBusitype()));

            //  获取凭证详情列表
            //  @param vo 凭证主数据对象，用于查询凭证的详细信息
            // * @return 返回凭证详情的列表
            List<VoucherDetailVO> listDe = this.getDetail(vo); //baseDataMapper.findVoucherDetailVO(vo.getVoSn());

            // 根据业务类型从配置中获取对应的流程步骤，并分割为数组
            // @param vo 业务凭证对象，其中包含了业务类型
            String[] step = PzkConfig.StepMap.get(String.valueOf(vo.getBusitype())).split("-");// new String[]{"1","2","3","4"};


            for (String s : step) {
                try {

                    int pp = Integer.parseInt(s);
                    //查看模版页  根据类型名称和页码
                    //		VouTempPageVO vouTempPageVO=voucherDAO.findVouTemPage(vocde, pp);
                    VouTempPageVO vouTempPageVO = FindVouTemPage(listvp, vocode, pp);

                    // 定义一个SimpleDateFormat对象，用于格式化日期时间，格式为年月日时（例如：2022022216）
                    SimpleDateFormat formatP = new SimpleDateFormat("yyyyMMddHH");

                    // 定义一个SimpleDateFormat对象，用于格式化日期时间，格式为年月日时分秒（例如：20220222165905 123456）
                    SimpleDateFormat formats = new SimpleDateFormat("yyyyMMddHHmm ssSSS");

                    // 获取当前时间，格式化为年月日时分秒格式，并赋值给timePath变量
                    String timePath = formats.format(new Date());

                    // 获取当前时间，格式化为年月日时格式，并赋值给datePath变量
                    String datePath = formatP.format(new Date());

                    // 生成一个随机整数，并赋值给randomInt变量
                    String randomInt = getRandom();

                    // 根据给定参数生成文件路径
                    String filepath = pzkFilePath + datePath + File.separator + vo.getBusitype() + "_" + pp + "_" + timePath + "_" + randomInt + ".jpg";

                    // 生成用于查询时的文件访问路径
                    String savePath = datePath + "/" + vo.getBusitype() + "_" + pp + "_" + timePath + "_" + randomInt + ".jpg";

                    // 创建新的VoucherFileVO对象
                    VoucherFileVO voucherFileVO = new VoucherFileVO();

                    // 设置vfId，基于vo.getBusitype()生成唯一ID
                    voucherFileVO.setVfId(IdWorker.getOrderCode(vo.getBusitype()));

                    // 设置busiorderno，使用vo中的busiorderno
                    voucherFileVO.setBusiorderno(vo.getBusiorderno());

                    // 设置voPage，使用pp变量
                    voucherFileVO.setVoPage(pp);

                    // 设置voSn，使用vo中的voSn
                    voucherFileVO.setVoSn(vo.getVoSn());

                    // 设置voFilePath，使用刚生成的savePath
                    voucherFileVO.setVoFilePath(savePath);

                    // 设置创建时间，使用当前日期
                    voucherFileVO.setCreatetime(new Date());

                    // 保存凭证文件信息到数据库
                    if (voucherService.saveVoucherFile(voucherFileVO) > 0) {
                        log.info("Success");
                    } else {
                        log.info("Failed");
                    }


                    //根据模版ID   联页ID  印章ID 查询  印章位置，可以预设到内存中
                    //		List<VouandSealVO> listvs
                    //		VouandSealVO vouandSealVO=voucherDAO.findVouandSealVO(vouTempPageVO.getVO_TEMP_ID(), vouTempPageVO.getID(), "1");
                    VouandSealVO vouandSealVO = FindVouandSealVO(listvs, vouTempPageVO.getVoTempId(), vouTempPageVO.getId());

                    // 根据VouTempPageVO的ID获取VoucherTempPageVO对象
                    VouTempPageVO vouTemPage = getBlob.findVouTemPage(vouTempPageVO.getId());
                    // 根据Vv的ID获取VouSealVO对象
                    VouSealVO vouSealVO = getBlob.findVouSealVO(vv.getId());

                    byte[] voucherPager = null;
                    if (vouTemPage.getTemp() != null) {
                        voucherPager = ImageUtils.pressTextList(vouTemPage.getTemp(), listDe);
                    }

                    //查询机构代码 、机构类型  印章类型查询印章图片
                    //	VouSealVO  vouSealVO= voucherDAO.findVOUSEAL(vo1.getBankid(), 1, 1);
                    if (vouSealVO.getSealByte() != null) {
                        if (vouandSealVO.getSealPos() != null) {
                            // 添加图片水印
                            voucherPager = ImageUtils.pressImage(voucherPager, vouSealVO.getSealByte(), Integer.parseInt(vouandSealVO.getSealPos().split(",")[0]), Integer.parseInt(vouandSealVO.getSealPos().split(",")[1]), 1f);
                            log.info("水印添加成功！");
                        }
                    }

                    BufferedImage bi1 = null;
                    if (voucherPager != null) {
                        bi1 = ImageIO.read(new ByteArrayInputStream(voucherPager));
                    }

                    File f = new File(filepath);
                    if (!f.exists()) {
                        File parentDir = f.getParentFile();// 创建目录
                        boolean dirCreated = parentDir.mkdirs(); // 检查目录是否成功创建
                        if (!dirCreated && !parentDir.exists()) {
                            // 处理目录创建失败
                            log.error("目录创建失败" + parentDir.getAbsolutePath());
                        } else {
                            boolean fileCreated = f.createNewFile(); // 检查文件是否成功创建
                            if (!fileCreated) {
                                // 处理文件创建失败的情况
                                log.error("Failed to create the file: " + f.getAbsolutePath());
                            } else {
                                // 缩略图处理
                                try {
                                    Thumbnails.of(bi1).scale(scaling).outputQuality(compress).toFile(f);
                                } catch (IOException e) {
                                    // 处理缩略图处理失败的情况
                                    log.error("Failed to create a thumbnail for: " + f.getAbsolutePath(), e);
                                }
                            }
                        }
                    }

                    if (voucherMapper.updateVoucherDraw(vo.getVoSn()) < 1) {
                        log.info("绘制凭证后更新状态失败。vo_sn={}", vo.getVoSn());
                    }
                } catch (Exception e) {
                    log.info("画图异常。", e);
                }
            }
        }

        log.info("执行任务消耗了 ：" + (System.currentTimeMillis() - start) + "毫秒" + "~~~~~~~~~~~约等于~~~~~~~~~~" + (System.currentTimeMillis() - start) / 1000 + "秒");
        log.info("结束画图");
    }

    /**
     * 在给定的VouTempPageVO对象列表中查找指定VO_SN和页码(pp)的VouTempPageVO对象。
     *
     * @param listAll 包含VouTempPageVO对象的列表。
     * @param VO_SN 指定的VO_SN编码。
     * @param pp 指定的页码。
     * @return 如果找到匹配的VouTempPageVO对象则返回之，否则返回一个空的VouTempPageVO对象。
     */
    private VouTempPageVO FindVouTemPage(List<VouTempPageVO> listAll, String VO_SN, int pp) {
        // 遍历列表，查找匹配VO_SN和页码的VouTempPageVO对象
        for (VouTempPageVO vouTempPageVO : listAll) {
            if (vouTempPageVO.getVoPage().equals(pp + "") && vouTempPageVO.getVoCode().equals(VO_SN)) {
                return vouTempPageVO;
            }
        }
        return new VouTempPageVO();
    }

    /**
     * 在给定的VouandSealVO对象列表中查找指定vo_id和page_id的VouandSealVO对象。
     *
     * @param listAll 包含VouandSealVO对象的列表。
     * @param vo_id 指定的vo_id。
     * @param page_id 指定的page_id。
     * @return 如果找到匹配的VouandSealVO对象则返回之，否则返回一个空的VouandSealVO对象。
     */
    private VouandSealVO FindVouandSealVO(List<VouandSealVO> listAll, String vo_id, String page_id) {
        // 遍历列表，查找匹配vo_id和page_id的VouandSealVO对象
        for (VouandSealVO vouandSealVO : listAll) {
            if (vouandSealVO.getVoId().equals(vo_id) && vouandSealVO.getVoPageId().equals(page_id)) {
                return vouandSealVO;
            }
        }
        return new VouandSealVO();
    }

    /**
     * 随机数获取
     *
     * @return 随机数
     */
    public String getRandom() {
        Random random = new Random();
        int randomNumber = random.nextInt(900000) + 100000;
        return String.valueOf(randomNumber);
    }

    /**
     * 根据传入的券信息获取详情列表。
     *
     * @param vo 包含券业务类型和其他必要信息的对象
     * @return 返回券详情的VO对象列表，具体返回内容根据不同的业务类型动态决定
     */
    public List<VoucherDetailVO> getDetail(VoucherVO vo) {
        // 根据业务类型获取券模板页面信息
        VouTempPageVO vouTempPageVO = voucherService.getVouTempPage(PzkConfig.VocodeMap.get(String.valueOf(vo.getBusitype())), 1);

        // 查询并获取券的输出字段和位置信息
        List<VouFieldVO> list = voucherService.getVouField(vouTempPageVO.getId());

        // 根据不同的业务类型，调用相应的服务获取详情信息
        switch (vo.getBusitype()) {
            case PzkConfig.Pztype_EticketNum:
                return EticketNumService.getDetail(list, vo);
            case PzkConfig.Pztype_Student:
                return StudentService.getDetail(list, vo);
            case PzkConfig.Pztype_BackBill:
                return BackBillService.getDetail(list, vo);
            case PzkConfig.Pztype_Fisc:
                return FiscService.getDetail(list, vo);
            case PzkConfig.Pztype_Balance:
                return BalanceService.getDetail(list, vo);
            case PzkConfig.Pztype_WaitAffirm:
                return WaitAffirmService.getDetail(list, vo);
            case PzkConfig.Pztype_Divide:
                return DivideService.getDetail(list, vo);
            case PzkConfig.Pztype_Special:
                return SpecialService.getDetail(list, vo);
            case PzkConfig.Pztype_Illegal:
                return IllegalActivityService.getDetail(list, vo);
            case PzkConfig.Pztype_Deduct:
                return DeductService.getDetail(list, vo);
            case PzkConfig.Pztype_Zhichu:
                return WaitAffirmPayInfoService.getDetail(list, vo);
            case PzkConfig.Pztype_Cross:
                return IllegalActivityScaleInfoService.getDetail(list, vo);
            case PzkConfig.Pztype_ChargeBill:
                return ChargeBillService.getDetail(list, vo);
            default:
                // 若没有匹配的业务类型，返回空列表
                return new ArrayList<>();
        }
    }
}
